#include "cmdtask.h"

#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "commmsg.h"
#include "../instance/CInstanceMgr.h"


CT_REGISTER_ASYNCCMD(ID_MAIN_GET_TASK_LIST , CCmdGetTaskList);

int CCmdGetTaskList::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_GET_TASK_LIST ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_GET_TASK_LIST,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = stReq.gid();
    CT_TRACE(("get task list %u", uiGID));

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdGetTaskList::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    CUserTask& stUserTask = stPlayerOnlineData._stUserTask;

    //坐骑任务领取
    CTaskID stPreTaskID;
    stPreTaskID._uiBranchID = 0;
    stPreTaskID._uiTaskID = 991;

    CTaskID stMountTaskID;
    stMountTaskID._uiBranchID = 171;
    stMountTaskID._uiTaskID = 1;

    if (stUserTask.IsTaskFinished(stPreTaskID) 
        && !stUserTask.IsTaskFinished(stMountTaskID)
        && !stUserTask.IsValidTask(stMountTaskID)) //前置任务完成，尝试领坐骑任务
    {
        pstMainCtrl->m_stTaskMgr.AcceptTask(stMountTaskID, stUserTask);
    }

    pstMainCtrl->m_stTaskMgr.GetTaskList(stPlayerOnlineData._stUserTask, stAns);

    return AnsClients(RET_OK);
}


int CCmdGetTaskList::AnsClients(int iRet)
{
    pstMainCtrl->m_stEncodeBuf.Clear();

    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);
    stMsgHead.set_msgret(iRet);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);

    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, bFlushData))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_ACCEPT_TASK , CCmdAcceptTask);

int CCmdAcceptTask::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_ACCEPT_TASK ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_ACCEPT_TASK,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = stReq.gid();
    CT_TRACE(("accept task %u", uiGID));

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdAcceptTask::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CUserTask& stUserTask = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex]._stUserTask;

    //获取配置
    CTaskID stTaskID;
    stTaskID._uiBranchID = (unsigned int)stReq.task_id() / TASK_CONFIG_ID_MOD;
    stTaskID._uiTaskID = (unsigned int)stReq.task_id() % TASK_CONFIG_ID_MOD;

    CTaskConfigData stTaskConfigData;
    iRet = pstMainCtrl->m_stTaskMgr.GetTaskConfig(stTaskID, stTaskConfigData);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //检查领取NPC是否正确
    if (abs(stReq.npc_id()) != abs(stTaskConfigData._iAcceptNPC))
    {
        return AnsClients(ERROR_TASK_ACCEPT_NPC);
    }

    //领取任务
    iRet = pstMainCtrl->m_stTaskMgr.AcceptTask(stTaskID, stUserTask);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //保存数据
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("user %u not in hash", uiGID));
        //即使保存数据失败，也要正确返回
    }
    else
    {
        iRet = stUserTask.GetData(pstMainCtrl->m_stPlayerBaseInfoHash[iIndex]._stUserTaskData);
        if (iRet)
        {
            CT_WARNING(("get task data error , ret %d", iRet));
        }
        else
        {
            CVarObjectKey stKey;
            stKey.m_chDataType = DT_PLAYER_BASE_INFO;
            stKey.m_u64ID = uiGID;

            pstMainCtrl->UpdateData(stKey, pstMainCtrl->m_stPlayerBaseInfoHash[iIndex], VOP_UPDATE);
        }

        pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_TASK_LIST | NOTIFY_SYSOPEN_INFO);
    }

    return AnsClients(RET_OK);
}

int CCmdAcceptTask::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
    pstMainCtrl->FlushSendCache();
    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_COMMIT_TASK , CCmdCommitTask);

int CCmdCommitTask::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_COMMIT_TASK ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_COMMIT_TASK,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = stReq.gid();
    CT_TRACE(("commit task %u", uiGID));

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdCommitTask::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];
    
    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    CUserTask& stUserTask = stPlayerOnlineData._stUserTask;
    stUserTask.SetUserGid(uiGID);

    //获取配置
    CTaskID stTaskID;
    stTaskID._uiBranchID = (unsigned int)stReq.task_id() / TASK_CONFIG_ID_MOD;
    stTaskID._uiTaskID = (unsigned int)stReq.task_id() % TASK_CONFIG_ID_MOD;

    CTaskConfigData stTaskConfigData;
    iRet = pstMainCtrl->m_stTaskMgr.GetTaskConfig(stTaskID, stTaskConfigData);
    if (iRet)
    {
        return AnsClients(iRet);
    }

    //检查提交NPC是否正确
    if (abs(stReq.npc_id()) != abs(stTaskConfigData._iCommitNPC))
    {
        return AnsClients(ERROR_TASK_COMMIT_NPC);
    }

    //检查背包格是否足够
    CDropItem stDropItem;
    iRet = stUserTask.GetTaskAwardItems(stTaskConfigData, stDropItem);
    if (RET_OK != iRet)
    {
        return AnsClients(iRet);
    }

    //iRet = pstMainCtrl->m_stItemMgr.CheckBagFull(stPlayerOnlineData._stUserStorage, stPlayerOnlineData._stUserCard, stDropItem);
    if (pstMainCtrl->m_stItemMgr.CheckBagFull(stPlayerOnlineData._stUserStorage, stDropItem))
    {
        return AnsClients(ERROR_BAG_WILL_FULL);
    }

    //坐骑
    if (stReq.task_id() == 1710001)
    {
        iRet = pstMainCtrl->m_stMountMgr.CheckAddMount(stPlayerDetailEx1Info._stMount, 13);
        if (iRet)
        {
            return AnsClients(iRet);
        }
    }

    //提交任务
    if (stTaskID.IsRewardTask())
    {
        unsigned int uiPublishGID = pstMainCtrl->m_stTaskMgr.GetRewardTaskPublishGID(stUserTask, stTaskID);

        if (uiPublishGID == 0)
        {
            return AnsClients(ERROR_REWARD_TASK_ERROR12);
        }
        
        PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiPublishGID);

        int iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiPublishGID);
        if (iIndex < 0)
        {
            CT_ERROR(("no ex1 data user %u", uiPublishGID));
            return AnsClients(RET_SYSTEM_FAIL);
        }
        CPlayerDetailInfoEx1& stPublishDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

        iRet = pstMainCtrl->m_stTaskMgr.CommitRewardTask(stTaskID, stPublishDetailEx1Info._stRewardTask, stPlayerOnlineData);
        if (iRet == RET_OK)
        {
            //保存数据
            CVarObjectKey stKey;
            stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
            stKey.m_u64ID = uiPublishGID;
            pstMainCtrl->UpdateData(stKey, stPublishDetailEx1Info, VOP_UPDATE);

            //返回数据
            stAns.set_publish_gid(uiPublishGID);
            stAns.set_publisn_name(pstMainCtrl->m_stRoleMgr.GetRoleName(uiPublishGID));

            //通知发布者
            if (pstMainCtrl->m_stPlayerOnline.CheckOnline(uiPublishGID))
            {
                PBMsgHead stMsgHeadTemp;
                stMsgHeadTemp.set_time(CMainCtrl::m_pstMain->m_iNow);
                stMsgHeadTemp.set_msgact(0);
                stMsgHeadTemp.set_msgret(RET_OK);
                stMsgHeadTemp.set_msgid(ID_MAIN_AWARD_TASK);
                stMsgHeadTemp.set_msgtype(CSMsgDef::EMT_ANSWER);  

                CTBuffer& stEncodeBuf = CMainCtrl::m_pstMain->m_stEncodeBuf;
                stEncodeBuf.Clear();

                MsgAnsAwardTask stAwardTaskAns;
                stAwardTaskAns.set_opt(4);
                pstMainCtrl->m_stTaskMgr.GetMyRewardTaskList(stPublishDetailEx1Info._stRewardTask, uiPublishGID, stAwardTaskAns);
                pstMainCtrl->m_stTaskMgr.GetRewardTaskInfo(stPublishDetailEx1Info._stRewardTask, uiPublishGID, stAwardTaskAns);
                
                pstMainCtrl->EncodePBMsg(stMsgHeadTemp, stEncodeBuf);
                pstMainCtrl->EncodePBMsg(stAwardTaskAns, stEncodeBuf);
                pstMainCtrl->NotifyOnlineUser(uiPublishGID, stEncodeBuf);
                
            }
        }
    }
    else
    {
        iRet = pstMainCtrl->m_stTaskMgr.CommitTask(stTaskID, stUserTask);
        if (iRet)
        {
            return AnsClients(iRet);
        }

        //另坐骑
        if (stReq.task_id() == 1710001)
        {
            stPlayerDetailEx1Info._stMount.AddMount(13);

            CVarObjectKey stKey;
            stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
            stKey.m_u64ID = stPlayerDetailEx1Info._uiGID;
            pstMainCtrl->UpdateData(stKey, stPlayerDetailEx1Info, VOP_UPDATE);
        }
    }
    

    stDropItem.GetPBMsg(uiGID, *stAns.mutable_drop());

    for (int i = 0; i < stTaskConfigData._astFinishConds.Size(); ++i)
    {
        if (stTaskConfigData._astFinishConds[i]._ucCond == CTaskCond::TASK_GET_AND_COMMIT_ITEM)
        {
            //需要扣除道具
            
        }
    }

    //保存数据
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("user %u not in hash", uiGID));
        //即使保存数据失败，也要正确返回
    }
    else
    {
        iRet = stUserTask.GetData(pstMainCtrl->m_stPlayerBaseInfoHash[iIndex]._stUserTaskData);
        if (iRet)
        {
            CT_WARNING(("get task data error , ret %d", iRet));
        }
        else
        {
            CVarObjectKey stKey;
            stKey.m_chDataType = DT_PLAYER_BASE_INFO;
            stKey.m_u64ID = uiGID;

            pstMainCtrl->UpdateData(stKey, pstMainCtrl->m_stPlayerBaseInfoHash[iIndex], VOP_UPDATE);
        }
    }

    if (stTaskID.IsLessonTask())
    {
        CMainCtrl::m_pstMain->m_stDailyTaskMgr.TriggerTaskFinish(stPlayerOnlineData._stUserDailyTask, DAILY_TASK_ID_14);
    }
    

    pstMainCtrl->m_stNotifyMgr.Notify(stUserTask.GetUserGid(), NOTIFY_TASK_LIST | NOTIFY_SYSOPEN_INFO);

    return AnsClients(RET_OK);
}

int CCmdCommitTask::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }
    else
    {
        pstMainCtrl->m_stEncodeBuf.Clear();
        pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
        pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
        pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true);
    }

    return Done(iRet);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_USER_OPT , CCmdUserOpt);

int CCmdUserOpt::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_USER_OPT ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_USER_OPT,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return iRet;
    }
    //消息解析结束

    uiGID = stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return Done(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}


int CCmdUserOpt::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return Done(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = -1;
    /*
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no player data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];
    */

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return Done(RET_SYSTEM_FAIL);
    }
    CUserTask& stUserTask = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex]._stUserTask;

    unsigned char ucOpt = stReq.opt();

    switch(ucOpt)
    {
    case 1: //NPC对话
        {
            int iOptID = stReq.data() * TASK_OPT_CONFIG_ID_MOD + TASK_OPT_ID_108; 
            pstMainCtrl->m_stTaskMgr.TriggerDoSomeOpt(stUserTask, iOptID, 1);
        }
        break;
    default:
        return Done(RET_OK);
    }

    return Done(RET_OK);
}

//////////////////////////////////////////////////////////////////////////
CT_REGISTER_ASYNCCMD(ID_MAIN_AWARD_TASK , CCmdAwardTask);

int CCmdAwardTask::Do(void* pData)
{
    CT_ASSERT(pData);

    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_AWARD_TASK ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_AWARD_TASK,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    uiGID = stReq.gid();

    //检查登录
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdAwardTask::LogicDo(int iRet)
{
    if (iRet != 0)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    ASSERT_PLAYER_PREPARED(uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);

    int iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no base info, user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no detail ex1 info, user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no detail ex1 info, user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfoEx1& stPlayerDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];
    
    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("no online data user %u", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
    CUserTask& stUserTask = stPlayerOnlineData._stUserTask;
    stUserTask.SetUserGid(uiGID);

    stAns.set_opt(stReq.opt());

    bool bNeedSaveData = false;

    switch (stReq.opt())
    {
    case 1: //查询悬赏任务列表
        {
            pstMainCtrl->m_stTaskMgr.GetRewardTaskList(uiGID, stAns);
            pstMainCtrl->m_stTaskMgr.GetRewardTaskInfo(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
        }
        break;
    case 2: //发布任务
        {
            iRet = pstMainCtrl->m_stTaskMgr.PublishRewardTask(stPlayerDetailEx1Info._stRewardTask, stReq.task_type(), stPlayerBaseInfo, stPlayerOnlineData);

            if (RET_OK == iRet)
            {
                pstMainCtrl->m_stStorageMgr.GetData(stPlayerOnlineData._stUserStorage, stPlayerDetailInfo._stUserStorage);
                pstMainCtrl->m_stTaskMgr.GetMyRewardTaskList(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
                pstMainCtrl->m_stTaskMgr.GetRewardTaskInfo(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
            
                pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_BAG_INFO);
                bNeedSaveData = true;
            }
        }
        break;
    case 3: //接受任务
        {
            if (stPlayerBaseInfo._shLevel < 30)
            {
                return AnsClients(ERROR_REWARD_TASK_ERROR14);
            }

            unsigned int uiPublishGID = (unsigned int)stReq.publish_gid();
            PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiPublishGID);

            iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiPublishGID);
            if (iIndex < 0)
            {
                CT_ERROR(("no detail ex1 info, user %u", uiPublishGID));
                return AnsClients(RET_SYSTEM_FAIL);
            }
            CPlayerDetailInfoEx1& stPublishDetailEx1Info = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

            iRet = pstMainCtrl->m_stTaskMgr.AcceptRewardTask(stPlayerDetailEx1Info._stRewardTask, 
                                        stPublishDetailEx1Info._stRewardTask, stPlayerOnlineData, stReq.publish_time(),
                                        uiPublishGID, stAns);

            if (iRet == RET_OK)
            {
                stPlayerOnlineData._stUserTask.GetData(stPlayerBaseInfo._stUserTaskData);

                //保存数据
                CVarObjectKey stKey;
                stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
                stKey.m_u64ID = uiPublishGID;
                pstMainCtrl->UpdateData(stKey, stPublishDetailEx1Info, VOP_UPDATE);
                bNeedSaveData = true;

                //下发数据
                pstMainCtrl->m_stTaskMgr.GetRewardTaskInfo(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
                pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_TASK_LIST);
            }
        }
        break;
    case 4: //查询我的任务
        {
            pstMainCtrl->m_stTaskMgr.GetMyRewardTaskList(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
            pstMainCtrl->m_stTaskMgr.GetRewardTaskInfo(stPlayerDetailEx1Info._stRewardTask, uiGID, stAns);
        }
        break;
    case 5: //领取任务奖励
        {
            iRet = pstMainCtrl->m_stTaskMgr.GetRewardTaskBonus(stPlayerDetailEx1Info._stRewardTask, uiGID, stReq.publish_time(), stAns);
            if (iRet == RET_OK)
            {
                bNeedSaveData = true;
            }
        }
        break;
    default:
        iRet = RET_SYS_ERROR;
    }

    //保存数据
    if (bNeedSaveData)
    {
        CVarObjectKey stKey;
        stKey.m_chDataType = DT_PLAYER_BASE_INFO;
        stKey.m_u64ID = uiGID;
        pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

        stKey.m_chDataType = DT_PLAYER_DETAIL_INFO;
        stKey.m_u64ID = uiGID;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailInfo, VOP_UPDATE);

        stKey.m_chDataType = DT_PLAYER_DETAIL_EX1_INFO;
        stKey.m_u64ID = uiGID;
        pstMainCtrl->UpdateData(stKey, stPlayerDetailEx1Info, VOP_UPDATE);
    }
    
    return AnsClients(iRet);
}

int CCmdAwardTask::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }
    else
    {
        pstMainCtrl->m_stEncodeBuf.Clear();
        pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
        pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
        pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true);
    }

    return Done(iRet);
}